package dongze.com.ckdj.data.gson;

import android.util.Log;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.annotations.SerializedName;

import java.lang.reflect.Field;
import java.lang.reflect.Type;

import dongze.com.ckdj.util.MyLog;


/**
 * Created by fanqwz on 2017/7/25.
 */

//后端返回值不规范，空对象使用空的花括号，但是返回了空字符串，需要手动处理反序列化，并在实体类上使用注解
public class GsonNullDeserializer implements JsonDeserializer {
    private static final String TAG = GsonNullDeserializer.class.getSimpleName();

    Field mJsonPrimitiveValueField;

    public GsonNullDeserializer() {
        try {
            mJsonPrimitiveValueField = JsonPrimitive.class.getDeclaredField("value");
            mJsonPrimitiveValueField.setAccessible(true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        if (json.isJsonObject() && typeOfT instanceof Class) {
            JsonObject jsonObject = json.getAsJsonObject();
            try {
                Object o = ((Class) typeOfT).newInstance();
                Field[] fields = o.getClass().getDeclaredFields();

                for (Field f : fields) {
                    String name = null;

                    if (f.getAnnotation(SerializedName.class) != null)
                        name = f.getAnnotation(SerializedName.class).value();

                    if (name == null)
                        name = f.getName();

                    JsonElement element = jsonObject.get(name);

                    if (element == null)
                        continue;

                    f.setAccessible(true);
                    try {
                        f.set(o, context.deserialize(element, f.getGenericType()));
                    } catch (Exception e) {
                        e.printStackTrace();
                        MyLog.e(TAG, "deserialize: class:" + o + ",field:" + f, e);
                    }
                }

                return o;
            } catch (InstantiationException e) {
                MyLog.e(TAG, "deserialize: ", e);
            } catch (IllegalAccessException e) {
                MyLog.e(TAG, "deserialize: ", e);
            }
        }

        MyLog.e(TAG, "deserialize: parse type " + typeOfT + " return null, json is " + json);
        return null;
    }
}
